/*
 * Copyright (C) 2009 CityLights Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.schizoidman.android.citylights;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;

import com.schizoidman.android.citylights.model.TCBuildTypeProxy;
import com.schizoidman.android.citylights.model.TCProjectProxy;

public class WidgetRegistry {

	private static final String WIDGETS_DATABASE_NAME = "WidgetsDB"; 
	private static final String WIDGETS_DATABASE_TABLE = "t_Widgets12"; 

	private static final String DB_FIELD_WIDGET_ID = "Widget_id";
	private static final String DB_FIELD_URI = "Uri";
	private static final String DB_FIELD_USERNAME = "Username";
	private static final String DB_FIELD_PASSWORD = "Password";
	private static final String DB_FIELD_PROJECTNAME = "ProjectName";
	private static final String DB_FIELD_BUILDCONFIGNAME = "BuildConfigName";
    
    static Map<Context, WidgetRegistry> INSTANCEs = new HashMap<Context, WidgetRegistry>();
    
    static WidgetRegistry getRegistry(Context context) {
    	WidgetRegistry instance = INSTANCEs.get(context);
    	if (instance == null) {
    		instance = new WidgetRegistry(context);
    		INSTANCEs.put(context, instance);
    	}
    	return instance;
    }
    
	private SQLiteDatabase mWidgetsDB;
    
    private WidgetRegistry(Context context) {
        mWidgetsDB = context.openOrCreateDatabase(WIDGETS_DATABASE_NAME, Context.MODE_PRIVATE, null);
		mWidgetsDB.execSQL("CREATE TABLE IF NOT EXISTS " + WIDGETS_DATABASE_TABLE + " ( _id INTEGER PRIMARY KEY autoincrement, " 
				+ DB_FIELD_WIDGET_ID + " INTEGER, " 
				+ DB_FIELD_URI + " VARCHAR, " 
				+ DB_FIELD_USERNAME + " VARCHAR, " 
				+ DB_FIELD_PASSWORD + " VARCHAR, " 
				+ DB_FIELD_PROJECTNAME + " VARCHAR, "
				+ DB_FIELD_BUILDCONFIGNAME + " VARCHAR);"
		);
    }
    
   // Write preferences needed for widget in future 
   void saveWidgetPrefs(int appWidgetId, Intent intent) {
		ContentValues cv = new ContentValues();
		Bundle data = intent.getExtras();

		Log.d("CityLights", "Saving widget to the database: " + appWidgetId + ":" + intent.getDataString());

		cv.put(DB_FIELD_WIDGET_ID, appWidgetId);
		cv.put(DB_FIELD_URI, intent.getDataString());
		cv.put(DB_FIELD_USERNAME, data.getString("username"));
		cv.put(DB_FIELD_PASSWORD, data.getString("password"));
		cv.put(DB_FIELD_PROJECTNAME, data.getString(TCProjectProxy.NAME));
		cv.put(DB_FIELD_BUILDCONFIGNAME, data.getString(TCBuildTypeProxy.NAME));
		
		int updated = mWidgetsDB.update(WIDGETS_DATABASE_TABLE, cv, DB_FIELD_WIDGET_ID + " = " + appWidgetId, null);
		if (updated <= 0) {
			// If there were no rows to update, lets create the new one
			mWidgetsDB.insert(WIDGETS_DATABASE_TABLE, "", cv);
		}
   }

    // Read widget preferences. Returns null if widget is not yet initialized
    Intent loadWidgetPrefs (int appWidgetId) {
		Intent result = null;
    	Cursor c = mWidgetsDB.query(WIDGETS_DATABASE_TABLE, null, DB_FIELD_WIDGET_ID + " = " + appWidgetId, null, null, null, null);
    	if (c.moveToFirst()) {
    		result = loadWidgetPrefs(c);
    	}
    	c.close();
        return result;
    }
    
    // Enumerates all stored widget IDs, returns an iterator over all stored Intents.
    Iterator<Intent> widgetIterator() {
    	return new Iterator<Intent>() {
    		Cursor c = mWidgetsDB.query(WIDGETS_DATABASE_TABLE, null, null, null, null, null, null);
    		boolean isEmpty = c.getCount() <= 0;
    		
    		public boolean hasNext() {
    			if (c.isClosed()) {
    				return false;
    			} else if (isEmpty || c.isLast()) {
    				c.close();
    				return false;
    			}
    			return true;
    		}
    		
    		public Intent next() {
    			c.moveToNext();
    			return loadWidgetPrefs(c);
    		}

    		// not supported
    		public void remove() {
    			throw new UnsupportedOperationException("Remove operation is not supported for this iterator");
			}
    		
    		@Override
    		protected void finalize() throws Throwable {
    			c.close();
    			super.finalize();
    		}
    	};
    }
    
    
    // Read widget preferences from the cursor. Moves the cursor to the next position before reading.
    private Intent loadWidgetPrefs (Cursor c) {
//    	c.moveToNext();
	
		Log.d("CityLights", "Restoring widget from the database: " + c.getInt(c.getColumnIndex(DB_FIELD_WIDGET_ID))
				+ ":" + c.getString(c.getColumnIndex(DB_FIELD_URI)));

		Intent result = new Intent();
		result.setData(Uri.parse(c.getString(c.getColumnIndex(DB_FIELD_URI))));
		result.putExtra("username", c.getString(c.getColumnIndex(DB_FIELD_USERNAME)));
		result.putExtra("password", c.getString(c.getColumnIndex(DB_FIELD_PASSWORD)));
		result.putExtra(TCProjectProxy.NAME, c.getString(c.getColumnIndex(DB_FIELD_PROJECTNAME)));
		result.putExtra(TCBuildTypeProxy.NAME, c.getString(c.getColumnIndex(DB_FIELD_BUILDCONFIGNAME)));
		result.putExtra("widget.id", c.getInt(c.getColumnIndex(DB_FIELD_WIDGET_ID)));
        return result;
    }	
    
    // Erases widget preferences for when the widget was removed from the dashboard
    void eraseWidgetPrefs(int appWidgetId) {
		Log.d("CityLights", "Erasing widget from the database: " + appWidgetId);
    	mWidgetsDB.delete(WIDGETS_DATABASE_TABLE, DB_FIELD_WIDGET_ID + " = " + appWidgetId, null);
    }
    
    // Purges all widget table
    void purgeWidgetPrefs() {
		Log.d("CityLights", "Purging widget table: ");
    	mWidgetsDB.delete(WIDGETS_DATABASE_TABLE, DB_FIELD_WIDGET_ID + " = *", null);
    }
        
    @Override
    protected void finalize() throws Throwable {
    	mWidgetsDB.close();
    	super.finalize();
    }
 
	
}
